package cloud.seri.gateway.web.rest

import cloud.seri.gateway.security.oauth2.OAuth2AuthenticationService
import org.slf4j.LoggerFactory
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.oauth2.common.OAuth2AccessToken
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * Authentication endpoint for web client.
 * Used to authenticate a user using OAuth2 access tokens or log him out.
 *
 * @author markus.oellinger
 */
@RestController
@RequestMapping("/auth")
class AuthResource(private val authenticationService: OAuth2AuthenticationService) {

    private val log = LoggerFactory.getLogger(AuthResource::class.java)

    /**
     * Authenticates a user setting the access and refresh token cookies.
     *
     * @param request the [HttpServletRequest] holding - among others - the headers passed from the client.
     * @param response the [HttpServletResponse] getting the cookies set upon successful authentication.
     * @param params the login params (username, password, rememberMe).
     * @return the access token of the authenticated user. Will return an error code if it fails to authenticate the user.
     */
    @RequestMapping(value = ["/login"], method = [RequestMethod.POST], consumes = [MediaType
        .APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun authenticate(
        request: HttpServletRequest,
        response: HttpServletResponse,
        @RequestBody
        params: Map<String, String>
    ): ResponseEntity<OAuth2AccessToken> {
        return authenticationService.authenticate(request, response, params)
    }

    /**
     * Logout current user deleting his cookies.
     *
     * @param request the [HttpServletRequest] holding - among others - the headers passed from the client.
     * @param response the [HttpServletResponse] getting the cookies set upon successful authentication.
     * @return an empty response entity.
     */
    @RequestMapping(value = ["/logout"], method = [RequestMethod.POST])
    fun logout(request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<*> {
        log.info("logging out user {}", SecurityContextHolder.getContext().authentication.name)
        authenticationService.logout(request, response)
        return ResponseEntity.noContent().build<Any>()
    }
}
